<script lang="ts" setup>
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
import User from '@iconify-icons/ri/user-3-fill';
import Lock from '@iconify-icons/ri/lock-fill';
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { useUserStore } from '@/store/system/user';
import { message } from '@/utils/message';
import { getTopMenu, initRouter } from '@/router/utils';
import Motion from './utils/motion';
import { ElMessage, FormInstance } from 'element-plus';
import { currentPage } from '@/views/login/utils/hooks';
import { formRules } from '@/views/login/utils/rule';
import { fetchCaptcha } from '@/api/system/adminUser';

const router = useRouter();
const userStore = useUserStore();
const ruleFormRef = ref<FormInstance>();
const loading = ref(false);
const { t } = useI18n();
const captchaImage = ref('');
const captchaKey = ref('');

const ruleForm = reactive({
	username: '',
	password: '',
	captchaCode: '',
	captchaKey: '',
	type: currentPage.value,
});

/**
 * 获取验证码
 */
const getCaptcha = async () => {
	try {
		const result = await fetchCaptcha();
		if (result && result.code === 200 && result.data) {
			// 后端直接返回完整的data:image/png;base64格式的图片数据
			captchaImage.value = result.data.captchaImage;
			captchaKey.value = result.data.captchaKey;
			ruleForm.captchaKey = result.data.captchaKey;
		}
	} catch (error) {
		message('获取验证码失败', { type: 'error' });
	}
};

/**
 * 登录
 * @param formEl
 */
const onLogin = async (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	await formEl.validate(async valid => {
		if (valid) {
			loading.value = true;
			const result = await userStore.loginByUsername(ruleForm);

			if (result) {
				// 获取后端路由
				await initRouter();
				router.push(getTopMenu(true).path).then(() => {
					ElMessage.closeAll();
					message(t('loginSuccess'), { type: 'success' });
				});
			} else {
				// 登录失败后刷新验证码
				getCaptcha();
			}

			loading.value = false;
		}
	});
};

/** 使用公共函数，避免`removeEventListener`失效 */
function onkeypress({ code }: KeyboardEvent) {
	if (['Enter', 'NumpadEnter'].includes(code)) {
		onLogin(ruleFormRef.value);
	}
}

// 刷新验证码
const refreshCaptcha = () => {
	getCaptcha();
};

onMounted(() => {
	window.document.addEventListener('keypress', onkeypress);
	getCaptcha();
});

onBeforeUnmount(() => {
	window.document.removeEventListener('keypress', onkeypress);
});
</script>

<template>
	<el-form ref="ruleFormRef" :model="ruleForm" :rules="formRules" size="large">
		<Motion>
			<el-form-item prop="username">
				<el-input v-model="ruleForm.username" :placeholder="t('login.username')" :prefix-icon="useRenderIcon(User)" clearable />
			</el-form-item>
		</Motion>

		<Motion :delay="150">
			<el-form-item prop="password">
				<el-input v-model="ruleForm.password" :placeholder="t('login.password')" :prefix-icon="useRenderIcon(Lock)" clearable show-password />
			</el-form-item>
		</Motion>

		<Motion :delay="200">
			<el-form-item prop="captchaCode">
				<el-input v-model="ruleForm.captchaCode" :placeholder="t('login.captchaCode') || '请输入验证码'" clearable>
					<template #append>
						<div class="captcha-container" @click="refreshCaptcha">
							<img v-if="captchaImage" :src="captchaImage" alt="验证码" class="captcha-image" />
							<span v-else>加载中...</span>
						</div>
					</template>
				</el-input>
				<el-checkbox v-model="userStore.isRemembered">
					<el-text size="small" type="primary">{{ userStore.readMeDay }}天免登录</el-text>
				</el-checkbox>
			</el-form-item>
		</Motion>

		<Motion :delay="250">
			<el-form-item>
				<el-button :loading="loading" class="w-full" size="default" type="primary" @click="onLogin(ruleFormRef)">
					{{ t('loginButton') }}
				</el-button>
			</el-form-item>
		</Motion>
	</el-form>
</template>

<style scoped>
.captcha-container {
	cursor: pointer;
	height: 100%;
	width: 100px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-left: 1px solid #dcdfe6;
	border-right: 1px solid #dcdfe6;
	background-color: #f5f7fa;
	transition: all 0.3s;
	border-top-right-radius: 4px;
	border-bottom-right-radius: 4px;
}

.captcha-container:hover {
	background-color: #e6ebf5;
}

.captcha-image {
	height: 36px;
	max-width: 100%;
	border-radius: 2px;
}

/* 处理深色模式 */
:deep(.dark) .captcha-container {
	border-color: #434343;
	background-color: #333333;
}

:deep(.dark) .captcha-container:hover {
	background-color: #393939;
}
</style>
